package com.mie.service.impl;

import com.mie.entity.FileData;
import com.mie.repository.FileRepository;
import com.mie.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author Mie
 * @Description
 * @Date 2021/11/11 13:52
 **/
@Service
public class FileServiceImpl implements FileService {

    //获取上传的文件存放的位置
    @Value("${files.path.upload}")
    private String uploadPath;

    @Autowired
    private FileRepository fileRepository;

    //文件输入流
    FileOutputStream fos;
    //文件输出流
    FileInputStream fis;
    //输出流
    OutputStream os;

    /**
     * @Description  根据uuid获取文件信息
     * @Param [newName]
     * @return [java.lang.String]
     **/
    @Override
    public Map getFileData(String newName) {
        Map map = new HashMap();

        //获取文件元信息
        FileData fileData = fileRepository.selectFileDataByNewName(newName);

        map.put("fileData",fileData);

        return map;
    }

    /**
     * @Description 上传文件
     * @Param [file]
     * @return [org.springframework.web.multipart.MultipartFile]
     **/
    @Override
    public Map uploadFile(MultipartFile file) {

        Map map = new HashMap();
    FileData fileData = new FileData();

    //获取uuid
    String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        map.put("uuid",uuid);

    //获取文件原始名
    String oldName = file.getOriginalFilename();

    //获取后缀
    String suffix = oldName.substring(oldName.lastIndexOf("."));

    //重命名文件名
    String newName = uuid + suffix;


    //目录格式
    Date date = new Date();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

    //文件的目录
    String list = uploadPath + "/" + simpleDateFormat.format(date) + "/";

    //文件的路径
    String filePath = list + newName;

        try {
        //获取文件字节数组
        byte[] bytes = file.getBytes();
        //如果目录不存在，则创建
        File dest = new File(list);
        if (!dest.exists()) {
            dest.mkdirs();
        }

        //创建文件输出
        fos = new FileOutputStream(filePath);
        fos.write(bytes);

        map.put("msg","文件上传成功");
    } catch (IOException e) {
        throw new RuntimeException("上传文件失败,服务器发生异常!", e);
    } finally {
        //关闭流
        try {
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //将数据放入FileData中
        fileData.setSize(file.getSize());
        fileData.setType(file.getContentType());
        fileData.setOldName(oldName);
        fileData.setNewName(uuid);
        fileData.setFilePath(filePath);

    //存入数据库
        fileRepository.saveFileData(fileData);

        return map;
    }

    /**
     * @Description 根据uuid下载文件
     * @Param [newName, rs]
     * @return [java.lang.String, javax.servlet.http.HttpServletResponse]
     **/
    @Override
    public void downloadFile(String newName, HttpServletResponse rs) {
        //设置响应类型
        rs.setContentType("application/octet-stream");

        FileData fileData = fileRepository.selectFileDataByNewName(newName);

        String oldName = fileData.getOldName();
        String suffix = oldName.substring(oldName.lastIndexOf("."));

        rs.addHeader("Content-Disposition", "attachment;fileName=" + newName + suffix);
        if (fileData == null) {
            rs.setStatus(410);
            return;
        }

        //获取文件
        File file = new File(fileData.getFilePath());

        //判断文件存在与否,不存在返回410状态码
        if (file.exists()) {
            try {
                fis = new FileInputStream(file);
                os = rs.getOutputStream();

                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = fis.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }
            } catch (IOException e) {
                throw new RuntimeException("读取文件失败", e);
            } finally {
                //关闭流
                try {
                    fis.close();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            rs.setStatus(410);
        }
    }
}
